package model

import (
	ryrpc "admin/rpc"
	myConfig "common/config"
	myconn "common/conn"
	"common/helper"
	myredis "common/redis"
	myUserHelp "common/userHelp"
	"crypto/md5"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/speps/go-hashids"
	"github.com/valyala/fasthttp"
	"math"
	"math/rand"
	"regexp"
	"strconv"
	"strings"
	"time"

	g "github.com/doug-martin/goqu/v9"
	"github.com/doug-martin/goqu/v9/exp"
)

// 查询用户单条数据
func MemberFindByUsername(username string) (ryrpc.TblMemberBase, error) {

	m := ryrpc.TblMemberBase{}

	ex := g.Ex{}
	if username != "" {
		ex["username"] = username
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select("*").Where(ex).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.UsernameErr)
	}

	return m, nil
}

// 查询用户单条数据
func MemberFindByRealname(username string) (ryrpc.TblMemberBase, error) {

	m := ryrpc.TblMemberBase{}

	ex := g.Ex{}
	if username != "" {
		ex["real_name"] = username
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select("*").Where(ex).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.UsernameErr)
	}

	return m, nil
}

// 查询渠道用户单条数据
func MemberFindByUnameAndOpeId(username, operatorId string) (ryrpc.TblMemberBase, error) {

	m := ryrpc.TblMemberBase{}

	ex := g.Ex{
		"username":    username,
		"operator_id": operatorId,
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select(colsMember...).Where(ex).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.UsernameErr)
	}

	return m, nil
}

// 查询业务员用户单条数据
func MemberFindByUnameAndProId(username, businessId string) (ryrpc.TblMemberBase, error) {

	m := ryrpc.TblMemberBase{}

	ex := g.Ex{
		"username":    username,
		"business_id": businessId,
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select(colsMember...).Where(ex).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.UsernameErr)
	}

	return m, nil
}

func MemberFindByOperatorId(operatorId string) ([]ryrpc.TblMemberBase, error) {

	var m []ryrpc.TblMemberBase

	ex := g.Ex{}
	if operatorId != "" {
		ex["operator_id"] = operatorId
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select(colsMember...).Where(ex).ToSQL()
	err := meta.MerchantDB.Select(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.OperatorIdErr)
	}

	return m, nil
}

func MemberFindByBusinessId(businessId string) ([]ryrpc.TblMemberBase, error) {

	var m []ryrpc.TblMemberBase

	ex := g.Ex{}
	if businessId != "" {
		ex["business_id"] = businessId
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select(colsMember...).Where(ex).ToSQL()
	err := meta.MerchantDB.Select(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.BusinessIdErr)
	}

	return m, nil
}

func MemberFindByUid(uid string) (ryrpc.TblMemberBase, error) {

	m := ryrpc.TblMemberBase{}

	ex := g.Ex{}
	if uid != "" {
		ex["uid"] = uid
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select("*").Where(ex).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.UsernameErr)
	}

	return m, nil
}

// 查询用户单条数据
func MemberFindByUidAndOpeId(uid, operatorId string) (ryrpc.TblMemberBase, error) {

	m := ryrpc.TblMemberBase{}

	ex := g.Ex{
		"tm.uid":         uid,
		"tm.operator_id": operatorId,
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select("tm.*", "mb.brl", "mpa.deposit", "mpa.deposit_num", "mpa.first_deposit", "mpa.withdraw", "mpa.withdraw_num", "mpa.running", "mpa.game_round", "mpa.game_tax", "mpa.game_winlost", "mpa.proxy_invite_bonus").
		LeftJoin(g.T("tbl_member_balance").As("mb"), g.On(g.Ex{"tm.uid": g.I("mb.uid")})).
		LeftJoin(g.T("tbl_member_proxy_accu").As("mpa"), g.On(g.Ex{"tm.uid": g.I("mpa.uid"), "mpa.level": 0})).Where(ex).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	if err == sql.ErrNoRows {
		return m, errors.New(helper.OperatorIdErr)
	}

	return m, nil
}

// 查询用户单条数据
func MemberFindByUidAndProId(uid, businessId string) (ryrpc.TblMemberBase, error) {

	m := ryrpc.TblMemberBase{}

	ex := g.Ex{
		"uid":         uid,
		"business_id": businessId,
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select(colsMember...).Where(ex).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.OperatorIdErr)
	}

	return m, nil
}

func MemberBalanceFindOne(uid string) (TblMemberBalance, error) {

	balance := TblMemberBalance{}
	query, _, _ := dialect.From("tbl_member_balance").Select(colsMemberBalance...).Where(g.Ex{"uid": uid}).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&balance, query)
	if err != nil {
		return balance, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return balance, err
}

type MemberData struct {
	ryrpc.TblMemberBase
	MemBalance
}

type MemberPageData struct {
	T int64                      `json:"total"`
	D []ryrpc.TblMemberBaseTotal `json:"d"`
	S ryrpc.TblMemberBaseTotal   `json:"s"`
}

func MemberList(param MemberListParam, ctx *fasthttp.RequestCtx) (MemberPageData, error) {
	data := MemberPageData{}

	where := "tester=1"
	oderBy := "created_at"
	oderType := "desc"

	changephone := 1
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		changephone = 0
		where += " and a.operator_id=" + loginUser.Operator
	} else if loginUser.Businsess != "" {
		changephone = 0
		where += " and a.business_id=" + loginUser.Businsess
	} else {
		//总后台登陆
		adminInfo, _ := GetAdminInfoById(loginUser.Admin)
		if adminInfo.GroupID == "1" || adminInfo.GroupID == "2" {
			//超级管理员
			changephone = 0
		} else {

			if adminInfo.ImportantInfo == 1 {
				changephone = 0
			}
		}
	}

	if param.Uid != "" {
		if param.Depth != 0 {
			uids := "0"
			if param.Depth == 1 {
				uids = GetAgentTeamByDepth(param.Uid, 1)
			}
			if param.Depth == 2 {
				uids = GetAgentTeamByDepth(param.Uid, 2)
			}
			if param.Depth == 3 {
				uids = GetAgentTeamByDepth(param.Uid, 3)
			}
			if param.Depth == 12 {
				uids = GetAgentTeamByLenth2(param.Uid, 2)
			}
			if param.Depth == 123 {
				uids = GetAgentTeamByLenth2(param.Uid, 3)
			}
			if param.Depth == 13 {
				uids1 := GetAgentTeamByDepth(param.Uid, 1)
				uids2 := GetAgentTeamByDepth(param.Uid, 3)
				uids = uids1 + "," + uids2
			}
			if param.Depth == 23 {
				uids1 := GetAgentTeamByDepth(param.Uid, 2)
				uids2 := GetAgentTeamByDepth(param.Uid, 3)
				uids = uids1 + "," + uids2
			}
			where += " and a.uid in(" + uids + ")"
		} else {
			if len(param.Uid) == 8 {
				where += " and a.uid=" + param.Uid
			} else {
				where += " and a.uid like '%" + param.Uid + "%'"
			}
		}
	}

	if param.Username != "" {
		where += " and a.username='" + param.Username + "'"
	}
	if param.Phone != "" {
		where += " and a.phone='" + param.Phone + "'"
	}
	if param.Prefix != "" {
		where += " and a.prefix like '%" + param.Prefix + "%'"
	}
	//if param.OperatorName != "" {
	//	Operator, _ := GetOperatorInfoByUsername(param.OperatorName)
	//	param.OperatorId = Operator.Id
	//}
	if param.OperatorName != "" {
		where += " and oi.operator_name like '%" + param.OperatorName + "%'"
	}

	if param.BusinessName != "" {
		Business, _ := GetBusinessInfoByUsername(param.BusinessName)
		param.BusinessId = Business.Id
	}
	if param.RegIp != "" {
		where += " and a.created_ip='" + param.RegIp + "'"
	}
	if param.BusinessId != "" {
		where += " and a.business_id=" + param.BusinessId
	}
	if param.OperatorId != "" {
		where += " and a.operator_id=" + param.OperatorId
	}
	if param.ParentId != "" {
		where += " and pb.parent_id='" + param.ParentId + "'"
	}
	if param.IsBloger == 1 {
		where += " and mcb.is_bloger=1"
	}
	if param.RegStartTime != "" {
		StartTime, _ := helper.TimeToLoc(param.RegStartTime, loc)
		where += " and a.created_at>='" + strconv.FormatInt(StartTime, 10) + "'"
	}
	if param.RegEndTime != "" {
		EndTime, _ := helper.TimeToLoc(param.RegEndTime, loc)
		where += " and a.created_at<'" + (strconv.FormatInt(EndTime, 10)) + "'"
	}
	if param.RechargeMin != "" {
		where += " and mpa.deposit>=" + param.RechargeMin
	}
	if param.RechargeMax != "" {
		where += " and mpa.deposit<=" + param.RechargeMax
	}
	if param.WithdrawMin != "" {
		where += " and mpa.withdraw>=" + param.WithdrawMin
	}
	if param.WithdrawMax != "" {
		where += " and mpa.withdraw<=" + param.WithdrawMax
	}
	if param.RechargeHiddenSwitch != "" {
		where += " and mcb.charge_hidden_button=" + param.RechargeHiddenSwitch
	}
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}
	order := oderBy + " " + oderType
	fmt.Println(where)
	table := "tbl_member_base"
	join := " left join tbl_member_balance as mb on mb.uid=a.uid"                 //玩家余额表
	join += " left join tbl_member_accu as     mpa on mpa.uid=a.uid"              //玩家统计表
	join += " left join tbl_proxy_base as     pb on pb.uid=a.uid"                 //代理表
	join += " left join tbl_member_controller_button as     mcb on mcb.uid=a.uid" //控制表

	join += " left join tbl_proxy_accu as pa on pa.uid=a.uid and pa.level=1" //控制表

	join += " left join tbl_operator_info as oi on oi.id=a.operator_id" //渠道表
	join += " left join tbl_business_info as bi on bi.id=a.business_id" //业务员表

	join += " left join (select uid,sum(amount) amount,sum(hidden_amount) f_hide_amount from tbl_deposit where state in(362,365) and is_first=0 group by uid) as d1 on d1.uid=a.uid"
	join += " left join (select uid,sum(amount) amount,sum(hidden_amount) s_hide_amount from tbl_deposit where state in(362,365) and is_first=1 group by uid) as d2 on d2.uid=a.uid"

	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from " + table + " as a " + join + " where " + where
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	field := "a.*" +
		",ifnull(mb.brl,0) as brl" +
		",ifnull(mpa.deposit,0) as deposit" +
		",ifnull(mpa.deposit_times,0) as deposit_times" +
		",ifnull(mpa.withdraw,0) as withdraw" +
		",ifnull(mpa.withdraw_times,0) as withdraw_times" +
		",ifnull(mpa.proxy_invite_bonus,0) as proxy_invite_bonus" +
		",ifnull(mpa.running,0) as running" +
		",ifnull(mpa.game_round,0) as game_round" +
		",ifnull(mpa.game_winlost - mpa.running,0) as game_tax" +
		",ifnull(mpa.totalWaged,0) as totalWaged" +
		",ifnull(mcb.is_bloger,0) as is_bloger" +
		",ifnull(pb.parent_id,'') as parent_id" +
		",ifnull(oi.operator_name,'') as operator_name" +
		",ifnull(bi.account_name,'') as business_name" +
		",ifnull(d1.amount,0) as other_deposit" +
		",ifnull(d2.amount,0) as first_deposit" +
		",ifnull(d1.f_hide_amount,0) as f_hide_amount" +
		",ifnull(d2.s_hide_amount,0) as s_hide_amount" +
		",ifnull(pa.team_num,0) as lv1_team_num" +
		",ifnull(pa.deposit_num,0) as lv1_deposit_num" +
		",ifnull(pa.deposit,0) as lv1_deposit" +
		",ifnull(pa.withdraw_num,0) as lv1_withdraw_num" +
		",ifnull(pa.withdraw,0) as lv1_withdraw"

	query := "select " + field + "  from " + table + " as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)

	err := meta.MerchantDB.Select(&data.D, query)

	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	for key, value := range data.D {
		if changephone == 1 {
			phone := value.Phone
			if len(phone) > 5 {
				(data.D)[key].Phone = phone[:3] + "****" + phone[len(phone)-5:]
				//(data.D)[key].Username = (data.D)[key].Phone
			}
		}
		//redis 取余额
		(data.D)[key].Brl = myredis.GetUserFieldFloat64(value.Uid, "tbl_member_balance:brl")
		(data.D)[key].Password = ""
		(data.D)[key].PayPassword = ""
	}

	//统计
	sfield := "ifnull(sum(d1.amount),0) other_deposit" +
		",ifnull(sum(d2.amount),0) first_deposit" +
		",ifnull(sum(d1.f_hide_amount),0) f_hide_amount" +
		",ifnull(sum(d2.s_hide_amount),0) s_hide_amount"
	query = "select " + sfield + " from " + table + " as a " + join + " where " + where

	err = meta.MerchantDB.Get(&data.S, query)

	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return data, nil
}

func MemberDetail(param MemberListParam, ctx *fasthttp.RequestCtx) (ryrpc.TblMemberBaseTotal, error) {
	data := ryrpc.TblMemberBaseTotal{}
	where := "1=1"
	oderBy := "created_at"
	oderType := "desc"

	changephone := 1
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		changephone = 0
		where += " and a.operator_id=" + loginUser.Operator
	} else if loginUser.Businsess != "" {
		changephone = 0
		where += " and a.business_id=" + loginUser.Businsess
	} else {
		//总后台登陆
		adminInfo, _ := GetAdminInfoById(loginUser.Admin)
		if adminInfo.GroupID == "1" || adminInfo.GroupID == "2" {
			//超级管理员
			changephone = 0
		} else {
			if adminInfo.ImportantInfo == 1 {
				changephone = 0
			}
		}
	}

	if param.Uid != "" {
		where += " and a.uid=" + param.Uid
	}
	if param.Username != "" {
		where += " and a.username='" + param.Username + "'"
	}
	if param.RegIp != "" {
		where += " and a.created_ip='" + param.RegIp + "'"
	}
	if param.BusinessId != "" {
		where += " and a.business_id=" + param.BusinessId
	}
	if param.OperatorId != "" {
		where += " and a.operator_id=" + param.OperatorId
	}
	if param.RegStartTime != "" {
		StartTime, _ := helper.TimeToLoc(param.RegStartTime, loc)
		where += " and a.created_at>='" + strconv.FormatInt(StartTime, 10) + "'"
	}
	if param.RegEndTime != "" {
		EndTime, _ := helper.TimeToLoc(param.RegEndTime, loc)
		where += " and a.created_at<'" + (strconv.FormatInt(EndTime, 10)) + "'"
	}
	if param.RechargeMin != "" {
		where += " and mpa.deposit>=" + param.RechargeMin
	}
	if param.RechargeMax != "" {
		where += " and mpa.deposit<=" + param.RechargeMin
	}
	if param.WithdrawMin != "" {
		where += " and mpa.withdraw>=" + param.WithdrawMin
	}
	if param.WithdrawMax != "" {
		where += " and mpa.withdraw<=" + param.WithdrawMax
	}
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}
	order := oderBy + " " + oderType

	table := "tbl_member_base"

	join := " left join tbl_member_balance as mb on mb.uid=a.uid"                 //玩家余额表
	join += " left join tbl_member_accu as     mpa on mpa.uid=a.uid"              //玩家统计表
	join += " left join tbl_proxy_base as     pb on pb.uid=a.uid"                 //代理表
	join += " left join tbl_member_controller_button as     mcb on mcb.uid=a.uid" //控制表
	join += " left join tbl_member_base as mb2 on mb2.uid=pb.parent_id"           //玩家表 取上级名称

	join += " left join tbl_operator_info as oi on oi.id=a.operator_id" //渠道表
	join += " left join tbl_business_info as bi on bi.id=a.business_id" //业务员表

	field := "a.*" +
		",ifnull(mb.brl,0) as brl" +
		",ifnull(mpa.deposit,0) as deposit" +
		",ifnull(mpa.deposit_times,0) as deposit_times" +
		",ifnull(mpa.withdraw,0) as withdraw" +
		",ifnull(mpa.withdraw_times,0) as withdraw_times" +
		",ifnull(mpa.proxy_invite_bonus+mpa.enable_first_deposit_to_parent,0) as proxy_invite_bonus" +
		",ifnull(mpa.running,0) as running" +
		",ifnull(mpa.game_round,0) as game_round" +
		",ifnull(mpa.game_winlost - mpa.running,0) as game_tax" +
		",ifnull(mcb.is_bloger,0) as is_bloger" +
		",ifnull(mpa.totalWaged,0) as totalWaged" +
		",ifnull(pb.parent_id,'') as parent_id" +
		",ifnull(oi.operator_name,'') as operator_name" +
		",ifnull(mb2.username,'') as parent_name" +
		",ifnull(bi.account_name,'') as business_name"

	query := "select " + field + "  from " + table + " as a " + join + " where " + where + " order by " + order + " limit 1"

	err := meta.MerchantDB.Get(&data, query)

	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	if changephone == 1 {
		phone := data.Phone
		if len(phone) > 5 {
			data.Phone = phone[:3] + "****" + phone[len(phone)-5:]
			data.Username = data.Phone
		}
	}
	//redis 取余额
	data.Brl = myredis.GetUserFieldFloat64(data.Uid, "tbl_member_balance:brl")
	data.EnableWithdraw = myUserHelp.GetEnableWithdrawMount(data.Uid)
	data.Password = ""
	data.PayPassword = ""
	query = "select ifnull(sum(amount),0) up_score from tbl_member_adjust  where state=2 and adjust_mode=1 and uid=" + param.Uid
	meta.MerchantDB.Get(&data.UpScore, query)

	query = "select ifnull(color_money_hand,0) as color_money_hand,ifnull(color_money_freeze,0) as color_money_freeze,ifnull(color_money_first_charge,0) as color_money_first_charge  from tbl_member_color_money where  uid=" + param.Uid
	meta.MerchantDB.Get(&data, query)
	return data, nil
}

func MemberListOpt(data MemberPageData, exportExcel int) (MemberPageData, [][]interface{}) {
	exportData := [][]interface{}{}
	for _, value := range data.D {
		if exportExcel == 1 {
			single := []interface{}{
				value.Uid,
				value.OperatorName,
				value.BusinessName,
				value.Username,
				value.Phone,
				value.Deposit,
				value.Withdraw,
				value.Brl,
			}
			exportData = append(exportData, single)
		}
	}
	return data, exportData
}

func MemberFlushAll() {

	var data []ryrpc.TblMemberBase

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select(colsMember...).ToSQL()
	err := meta.MerchantDB.Select(&data, query)
	if err != nil {
		return
	}

	filterable := []string{
		"username",
		"phone",
		"email",
	}
	sortable := []string{
		"created_at",
	}
	searchable := []string{
		"username",
	}

	b, err := helper.JsonMarshal(data)
	if err != nil {
		return
	}

	meta.Meili.DeleteIndex("members")
	index := meta.Meili.Index("members")
	index.UpdateFilterableAttributes(&filterable)
	index.UpdateSortableAttributes(&sortable)
	index.UpdateSearchableAttributes(&searchable)

	_, err = index.AddDocuments(b, "uid")
	if err != nil {
		return
	}

}

func MemberInsert(username, password, parentId, operatorId, businessId string, tester int, prefix string) error {

	if MemberExist(username) {
		return errors.New("用户已存在")
	}
	var phone, email string

	if strings.Contains(username, "@") {
		email = username
	}
	if helper.CtypeDigit(username) {
		phone = username
	}

	sid, err := meta.MerchantRedis.Incr(ctx, "id").Result()
	if err != nil {
		return pushLog(err, helper.RedisErr)
	}

	uid := fmt.Sprintf("%d", sid)
	myCode, err := shortURLGen(uid)
	if err != nil {
		return errors.New(helper.ServerErr)
	}

	ex := g.Ex{}
	if phone != "" {
		ex["phone"] = phone
		if MemberBindCheck(ex) {
			return errors.New(helper.PhoneExist)
		}
	}
	if email != "" {
		ex["email"] = email
		if MemberBindCheck(ex) {
			return errors.New(helper.EmailExist)
		}
	}

	parent := ryrpc.TblMemberBase{
		Uid: "0",
	}
	if parentId != "" {
		parent, err = MemberFindByUid(parentId)
		if err != nil {
			return errors.New(helper.UIDErr)
		}
	}
	createdAt := uint32(time.Now().Unix())
	paypwd := fmt.Sprintf("%d", pwdMurmurHash("123456", createdAt))

	pwd := fmt.Sprintf("%d", pwdMurmurHash(password, createdAt))
	m := ryrpc.TblMemberBase{
		Prefix:      prefix,
		Uid:         uid,
		Username:    username,
		Phone:       phone,
		Email:       email,
		Password:    pwd,
		CreatedIp:   "",
		CreatedAt:   createdAt,
		InviteCode:  myCode,
		Tester:      tester,
		PayPassword: paypwd,
		OperatorId:  "0",
		BusinessId:  "0",
	}
	if operatorId != "" {
		m.OperatorId = operatorId
	}
	if businessId != "" {
		m.BusinessId = businessId
	}
	tx, err := meta.MerchantDB.Begin() // 开启事务
	if err != nil {
		return pushLog(err, "数据库错误")
	}

	query, _, _ := dialect.Insert("tbl_member_base").Rows(&m).ToSQL()
	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	b := TblMemberBalance{
		Prefix:            prefix,
		Uid:               uid,
		Brl:               0,
		LockAmount:        0,
		UnlockAmount:      0,
		AgencyAmount:      0,
		DepositLockAmount: 0,
		AgencyLockAmount:  0,
	}
	query, _, _ = dialect.Insert("tbl_member_balance").Rows(&b).ToSQL()
	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	sign := PromoSignRecord{
		UID:       uid,
		Username:  username,
		Vip:       0,
		Sign1:     "0",
		Sign2:     "0",
		Sign3:     "0",
		Sign4:     "0",
		Sign5:     "0",
		Sign6:     "0",
		Sign7:     "0",
		Sign8:     "0",
		Sign9:     "0",
		Sign10:    "0",
		Sign11:    "0",
		Sign12:    "0",
		Sign13:    "0",
		Sign14:    "0",
		Sign15:    "0",
		Sign16:    "0",
		Sign17:    "0",
		Sign18:    "0",
		Sign19:    "0",
		Sign20:    "0",
		Sign21:    "0",
		Sign22:    "0",
		Sign23:    "0",
		Sign24:    "0",
		Sign25:    "0",
		Sign26:    "0",
		Sign27:    "0",
		Sign28:    "0",
		Sign29:    "0",
		Sign30:    "0",
		SignWeek1: "0",
		SignWeek2: "0",
		SignWeek3: "0",
		SignWeek4: "0",
		SignWeek5: "0",
		SignWeek6: "0",
		SignWeek7: "0",
	}
	query, _, _ = dialect.Insert("tbl_promo_sign_record").Rows(&sign).ToSQL()
	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	query = MemberClosureInsert(m.Uid, m.Pid)
	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if parent.Uid != "" && parent.Uid != "0" {

		inviteRecord := tblPromoInviteRecord{
			Id:             helper.GenId(),
			Uid:            parent.Uid,
			Username:       parent.Username,
			Lvl:            1,
			ChildUid:       uid,
			ChildUsername:  username,
			FirstDepositAt: 0,
			DepositAmount:  0,
			BonusAmount:    0,
			CreatedAt:      uint32(createdAt),
			State:          1,
		}
		query, _, _ = dialect.Insert("tbl_promo_invite_record").Rows(&inviteRecord).ToSQL()

		_, err = tx.Exec(query)
		if err != nil {
			_ = tx.Rollback()
			return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
		pt := g.Record{
			"invite_register_num": g.L("invite_register_num+1"),
		}
		query, _, _ = dialect.Update("tbl_member_base").Set(pt).Where(g.Ex{"uid": parent.Uid}).ToSQL()

		_, err = tx.Exec(query)
		if err != nil {
			_ = tx.Rollback()
			return pushLog(err, "数据库错误")
		}

		ut := g.Record{
			"invited": 1,
		}
		update, _, _ := dialect.Update("tbl_member_base").Set(ut).Where(g.Ex{"uid": uid}).ToSQL()

		_, err = tx.Exec(update)
		if err != nil {
			_ = tx.Rollback()
			return pushLog(err, "数据库错误")
		}
		//查询后台转盘开关是否开启
		if TurntableSwitch() {
			// 邀请成功,赠送一次转盘机会
			info := g.Record{
				"unuse_chance": g.L(fmt.Sprintf("unuse_chance+%d", 1)),
			}
			update, _, _ = dialect.Update("tbl_pdd_turntable_info").Set(info).Where(g.Ex{"uid": parent.Uid}).ToSQL()

			_, err = tx.Exec(update)
			if err != nil {
				_ = tx.Rollback()
				return pushLog(err, "数据库错误")
			}
		}
	}

	//查询后台转盘开关是否开启
	if TurntableSwitch() {
		//注册成功插入转盘信息
		p := ryrpc.TblPddTurntableInfo{
			Uid:         uid,
			UnuseChance: 1,
			UsedChance:  0,
			Amount:      0,
			HandAmount:  0,
			TotAmount:   0,
			Enabled:     1,
			CreatedAt:   int64(int(createdAt)),
			UpdatedAt:   int64(int(createdAt)),
		}
		query, _, _ = dialect.Insert("tbl_pdd_turntable_info").Rows(&p).ToSQL()
		_, err = tx.Exec(query)
		if err != nil {
			_ = tx.Rollback()
			return pushLog(err, "数据库错误")
		}
	}
	err = tx.Commit()

	err = BankcardInsert(username, uid, "PIX")
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil
}

// 检测会员账号是否已存在
func MemberExist(username string) bool {

	key := "member:" + username
	exists := meta.MerchantRedis.Exists(ctx, key).Val()
	if exists == 0 {
		return false
	}

	return true
}

// shortURLGen uri 原始url,返回短url
func shortURLGen(uri string) (string, error) {

	for i := 0; i < 100; i++ {

		shortCode := shortUrlGenCode()
		key := fmt.Sprintf("shortcode:%s", shortCode)

		err := meta.MerchantRedis.SetNX(ctx, key, uri, 0).Err()
		if err != nil {

			continue
			//return "", errors.New(helper.RedisErr)
		}

		return shortCode, nil
	}
	return "", errors.New(helper.RedisErr)
}

// shortUrlGenCode 传入ID生成短码
func shortUrlGenCode() string {

	hd := hashids.NewData()
	hd.Salt = helper.GenId()
	hd.MinLength = 6
	h, _ := hashids.NewWithData(hd)
	shortCode, _ := h.EncodeInt64([]int64{time.Now().UnixMilli()})
	return shortCode
}

func MemberBindCheck(ex g.Ex) bool {

	var id string

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select("uid").Where(ex).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&id, query)
	if err == sql.ErrNoRows {
		return false
	}

	return true
}

func MemberClosureInsert(nodeID, targetID string) string {

	if targetID == "0" {
		targetID = nodeID
	}
	t := "SELECT ancestor, " + nodeID + ",lvl+1 FROM tbl_members_tree WHERE descendant = " + targetID + " UNION SELECT " + nodeID + "," + nodeID + ",0"
	query := "INSERT INTO tbl_members_tree (ancestor, descendant,lvl) (" + t + ")"

	return query
}

func MemberUpdateBonus(uid string, canBonus int) error {

	record := g.Record{
		"can_bonus": canBonus,
	}
	query, _, _ := dialect.Update("tbl_member_base").Set(&record).Where(g.Ex{"uid": uid}).ToSQL()

	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil
}

func MemberUpdateBloger(uid string, IsBloger int) error {

	record := g.Record{
		"is_bloger": IsBloger,
	}
	query, _, _ := dialect.Update("tbl_member_base").Set(&record).Where(g.Ex{"uid": uid}).ToSQL()

	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil
}

func MemberUpdatePassword(uid string, Password string) error {

	record := g.Record{
		"password": Password,
	}
	query, _, _ := dialect.Update("tbl_member_base").Set(&record).Where(g.Ex{"uid": uid}).ToSQL()

	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil
}

func MemberUpdateRebate(uid string, canRebate int) error {

	record := g.Record{
		"can_rebate": canRebate,
	}
	query, _, _ := dialect.Update("tbl_member_base").Set(&record).Where(g.Ex{"uid": uid}).ToSQL()

	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil
}

func MemberUpdateState(uid string, state int, remake string) error {

	record := g.Record{
		//"state":  state,
		//"remake": remake,
	}
	if state != 0 {
		record["state"] = state
	}
	if remake != "" {
		record["remake"] = remake
	}
	query, _, _ := dialect.Update("tbl_member_base").Set(&record).Where(g.Ex{"uid": uid}).ToSQL()

	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil
}

func MemberUpdateAgentChannel(uid, cid string) error {
	return nil
}

func MemberUpdateFlowMultiple(uid, winFlowMultiple, loseFlowMultiple string) error {
	return nil
}

// 通过用户名获取用户在redis中的数据
func MemberCache(fctx *fasthttp.RequestCtx, name string) (ryrpc.TblMemberBase, error) {

	m := ryrpc.TblMemberBase{}
	if name == "" {
		value := fctx.UserValue("token")
		if value == nil {
			return m, errors.New(helper.UsernameErr)
		}
		name = string(value.([]byte))
		if name == "" {
			return m, errors.New(helper.UsernameErr)
		}
	}

	t := dialect.From("tbl_member_base")
	query, _, _ := t.Select(colsMember...).Where(g.Ex{"username": name}).Limit(1).ToSQL()
	err := meta.MerchantDB.Get(&m, query)
	if err != nil && err != sql.ErrNoRows {
		return m, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	if err == sql.ErrNoRows {
		return m, errors.New(helper.UsernameErr)
	}

	if m.InviteCode == "" {
		mycode, err := shortURLGen(m.Uid)
		if err == nil {
			// 更新会员信息
			query, _, _ = dialect.Update("tbl_member_base").Set(g.Record{"invite_code": mycode}).Where(g.Ex{"uid": m.Uid}).ToSQL()
			_, err = meta.MerchantDB.Exec(query)
		}
	}

	return m, nil
}

func MemberAddBonus(uid, username, amount string) error {
	return nil
}

func MemberAddReward(uid string, amount float64) error {
	//查询后台转盘开关是否开启
	if TurntableSwitch() {
		info, err := GetTurntableInfo(uid)
		if err != nil {
			return pushLog(err, "数据库错误")
		}

		tx, err := meta.MerchantDB.Begin()
		if err != nil {
			return pushLog(err, "数据库错误")
		}

		totAmount := info.Amount + info.HandAmount
		balAfter := totAmount + amount
		history := ryrpc.TblPddTurntableHistory{
			Id:           helper.GenId(),
			Uid:          uid,
			Amount:       amount,
			BeforeAmount: totAmount,
			AfterAmount:  balAfter,
			CreatedAt:    time.Now().Unix(),
			Type:         9,
			Remark:       "后台手动增加",
		}
		query, _, _ := dialect.Insert("tbl_pdd_turntable_history").Rows(history).ToSQL()

		_, err = tx.Exec(query)
		if err != nil {

			_ = tx.Rollback()
			return err
		}

		//更新转盘信息表
		ex := g.Ex{
			"uid": uid,
		}
		record := g.Record{
			"hand_amount": info.HandAmount + amount,
			"updated_at":  time.Now().Unix(),
		}
		query, _, _ = dialect.Update("tbl_pdd_turntable_info").Set(record).Where(ex).ToSQL()

		_, err = tx.Exec(query)
		if err != nil {

			_ = tx.Rollback()
			return err
		}

		_ = tx.Commit()
	}
	return nil
}

// GiveSpinChance 定时任务
// 1.注册开始计算 三天后将奖励字段清零，同时停止参加活动
// 2.每日赠送一次转盘机会
func GiveSpinChance() {
	//查询后台转盘开关是否开启
	if TurntableSwitch() {
		members, err := MemberFindByBusinessId("")
		if err != nil {

		}
		if len(members) > 0 {
			for _, mb := range members {
				// 注册三天后清零
				if time.Since(time.Unix(int64(mb.CreatedAt), 0)).Hours()/24 >= 3 {
					info := g.Record{
						"amount":      0,
						"hand_amount": 0,
						"enabled":     0,
					}
					query, _, _ := dialect.Update("tbl_pdd_turntable_info").Set(info).Where(g.Ex{"uid": mb.Uid}).ToSQL()

					_, err = meta.MerchantDB.Exec(query)
					if err != nil {

					}
				} else {
					// 活动有效期内,每日赠送一次转盘机会
					info := g.Record{
						"unuse_chance": g.L(fmt.Sprintf("unuse_chance+%d", 1)),
					}
					query, _, _ := dialect.Update("tbl_pdd_turntable_info").Set(info).Where(g.Ex{"uid": mb.Uid}).ToSQL()

					_, err = meta.MerchantDB.Exec(query)
					if err != nil {

					}
				}
			}
		}
	}
}

// 查询后台转盘开关是否开启
func TurntableSwitch() bool {
	cfgVal := myConfig.GetGameCfgInt(myConfig.CfgTurntableSwitch)

	if cfgVal == 1 {
		return true
	} else {
		return false
	}
}

// /测试号
type MemberTestPage struct {
	T int64                 `json:"total"`
	D []ryrpc.TblMemberTest `json:"d"`
	S uint                  `json:"s"`
}

// 测试号列表
func MemberTestList(page, pageSize int, startTime, endTime string, ctx *fasthttp.RequestCtx, ex g.Ex) (MemberTestPage, error) {

	data := MemberTestPage{}
	var err error
	if startTime != "" && endTime != "" {

		startAt, err := helper.TimeToLoc(startTime, loc)
		if err != nil {
			return data, errors.New(helper.TimeTypeErr)
		}

		endAt, err := helper.TimeToLoc(endTime, loc)
		if err != nil {
			return data, errors.New(helper.TimeTypeErr)
		}
		if startAt >= endAt {
			return data, errors.New(helper.QueryTimeRangeErr)
		}

		ex["created_at"] = g.Op{"between": exp.NewRangeVal(startAt, endAt)}
	}

	//验证是否是渠道登录，是的话查询该渠道的会员列表
	//agentData := TblOperatorInfo{}
	//query := "select * from tbl_operator_info where id=" + adminId
	////query, _, _ := dialect.From("tbl_operator_info").Select(g.COUNT("id")).Where(ex).ToSQL()
	//
	//err = meta.MerchantDB.Get(&agentData, query)
	//if err != nil && err != sql.ErrNoRows {
	//	return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	//}
	//if agentData.Id != "" {
	//	ex["operator_id"] = adminId
	//}
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		ex["operator_id"] = loginUser.Operator

	} else if loginUser.Businsess != "" {
		ex["business_id"] = loginUser.Businsess
	}

	t := dialect.From("tbl_member_test")
	if page >= 1 {
		query, _, _ := t.Select(g.COUNT("uid")).Where(ex).ToSQL()
		err = meta.MerchantDB.Get(&data.T, query)
		if err != nil && err != sql.ErrNoRows {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	offset := (page - 1) * pageSize
	var d []ryrpc.TblMemberTest
	query, _, _ := t.Select("id", "uid", "account_name", "password", "operator_id", "business_id", "create_at", "amount").Where(ex).Order(g.I("id").Desc()).Offset(uint(offset)).Limit(uint(pageSize)).ToSQL()

	err = meta.MerchantDB.Select(&d, query)
	if err != nil {

		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	if len(d) == 0 {
		return data, nil
	}
	data.D = d
	data.S = uint(pageSize)
	for key, value := range data.D {
		//redis 取余额
		(data.D)[key].Amount = myredis.GetUserFieldFloat64(strconv.Itoa(value.Uid), "tbl_member_balance:brl")
		(data.D)[key].RealName = myredis.GetUserFieldString(strconv.Itoa(value.Uid), "tbl_member_base:real_name")
	}
	return data, nil
}

// 测试号生成
func NewMembetTestId(amount float64, total int, pwd string, ctx *fasthttp.RequestCtx) error {

	loginUser := GetLoginUser(ctx)
	operator_id := "0"
	business_id := "0"
	if loginUser.Operator != "" {
		operator_id = loginUser.Operator
	} else if loginUser.Businsess != "" {
		businessinfo, _ := GetBusinessInfoById(loginUser.Businsess)
		operator_id = businessinfo.OperatorId
		business_id = loginUser.Businsess
	}

	db := meta.MerchantDB
	operatorQuoteData, _ := GetQuoteDataByOperatorId(operator_id)
	////数量额度判断
	if (operatorQuoteData.TestMemberNumUsed + total) > operatorQuoteData.TestMemberNum {
		return errors.New("额度不足")
	}
	operatorQuoteData.TestMemberNumUsed += total
	////上分额度判断
	//totalAmount := amount * float64(total)
	//if (operatorQuoteData.TestMemberUsed + totalAmount) > operatorQuoteData.TestMemberQuota {
	//	return errors.New("额度不足")
	//}
	//operatorQuoteData.TestMemberUsed += totalAmount
	maxUid := 0
	t := dialect.From("tbl_member_test")
	query, _, _ := t.Select(g.MAX("uid")).ToSQL()
	_ = meta.MerchantDB.Get(&maxUid, query)
	if maxUid == 0 {
		maxUid = 910000001
	}

	timenow := time.Now().Format("2006-01-02 15:04:05")
	memberTest := g.Record{
		"operator_id": operator_id,
		"business_id": business_id,
		"amount":      amount,
		"create_at":   timenow,
	}
	memberBase := g.Record{
		"operator_id":  operator_id,
		"business_id":  business_id,
		"tester":       2,
		"pay_password": 123456,
		"created_at":   time.Now().Unix(),
	}
	memberBalance := g.Record{
		"brl": amount,
	}
	for i := 0; i < total; i++ {
		tx, err := db.Begin()
		maxUid += 1
		//str_gameid := strings.Replace(strconv.Itoa(maxUid),"119","",-1)
		password := pwd
		if password == "" {
			password = GetRandStr()
		} else {
			pattern := `^[a-zA-Z0-9]{6,10}$`
			matched, err := regexp.MatchString(pattern, password)
			if matched == false {
				_ = tx.Rollback()
				return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), helper.PasswordFMTErr)
			}
		}

		//测试表
		memberTest["uid"] = maxUid
		memberTest["account_name"] = "11" + strconv.Itoa(maxUid)
		memberTest["password"] = password
		query, _, _ := dialect.Insert("tbl_member_test").Rows(memberTest).ToSQL()
		_, err = tx.Exec(query)
		if err != nil {
			_ = tx.Rollback()
			return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
		//玩家表
		Uid := strconv.Itoa(maxUid)
		memberBase["uid"] = Uid
		memberBase["username"] = "11" + Uid
		memberBase["phone"] = "11" + Uid
		memberBase["password"] = password // MurmurHash(password, uint32(time.Now().Unix()))
		sql := "select username from tbl_member_nickname order by rand() limit 1"
		real_name := ""
		meta.MerchantDB.Get(&real_name, sql)
		memberBase["real_name"] = real_name

		query, _, _ = dialect.Insert("tbl_member_base").Rows(memberBase).ToSQL()
		_, err = tx.Exec(query)
		if err != nil {
			_ = tx.Rollback()
			if strings.Contains(err.Error(), "Duplicate entry") {
				continue
			}
			return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
		//金额表
		memberBalance["uid"] = Uid
		query, _, _ = dialect.Insert("tbl_member_balance").Rows(memberBalance).ToSQL()
		_, err = tx.Exec(query)
		if err != nil {

			_ = tx.Rollback()
			return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
		_ = tx.Commit()
	}

	//更新额度

	err := UpdateQuote(operatorQuoteData)
	if err != nil {
		return err
	}
	_, err = meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	return nil
}

// /修改测试号密码
func UpdateMemberTestPsw(uid, password string) error {
	//query, _, _ := dialect.From("tbl_operator_info").Select(g.COUNT("*").As("total")).Where(g.Ex{"uid": uid}).ToSQL()
	//_, err := meta.MerchantDB.Exec(query)
	//if err != nil {
	//	return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	//}
	param := UpdateMemberParam{}
	param.Uid, _ = strconv.Atoi(uid)
	param.Key = "password"
	param.Value = password

	err := UpdateMemberInfo(param)
	if err != nil {
		return errors.New("数据库错误")
	}

	query, _, _ := dialect.From("tbl_member_test").Where(g.Ex{"uid": uid}).Update().Set(g.Record{"password": password}).ToSQL()

	_, err = meta.MerchantDB.Exec(query)
	if err != nil {
		return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return nil

}

func MD5(str string) string {
	data := []byte(str) //切片
	has := md5.Sum(data)
	md5str := fmt.Sprintf("%x", has) //将[]byte转成16进制
	return md5str
}

func GetRandStr() string {

	rand.Seed(time.Now().UnixNano())

	// 生成前三位随机字母
	randomLetters := make([]rune, 3)
	for i := range randomLetters {
		randomLetters[i] = rune('a') + rune(rand.Intn(int('z'-'a'+1)))
	}
	// 生成后三位随机数字
	randomDigits := rand.Intn(1000)
	// 组合成最终字符串
	randomString := fmt.Sprintf("%s%03d", string(randomLetters), randomDigits)
	return randomString
}

func UpdateMemberInfo(param UpdateMemberParam) error {
	var allows = map[string]bool{
		"password":     true,
		"pay_password": true,
		"state":        true,
		"remake":       true,
		"real_name":    true,
	}
	if _, ok := allows[param.Key]; ok != true {
		return errors.New("权限不足")
	}
	//userInfo, err := MemberFindByUid(strconv.Itoa(int(param.Uid)))

	//if err != nil {
	//	return err
	//}

	if param.Key == "password" {
		//param.Value = MD5(param.Value)
	}
	query, _, _ := dialect.Update("tbl_member_base").Set(g.Record{param.Key: param.Value}).Where(g.Ex{"uid": param.Uid}).ToSQL()
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return errors.New("数据库错误")
	}
	//更新缓存
	ret := myredis.SetUserFieldValue(strconv.Itoa(int(param.Uid)), "tbl_member_base:"+param.Key, param.Value)
	if ret == false {
		return errors.New(helper.ServerErr)
	}
	return nil
}

func GetMemberController(uid int, ctx *fasthttp.RequestCtx) (MemberControllerButton, error) {
	data := MemberControllerButton{}

	query := fmt.Sprintf("select * from tbl_member_controller_button where uid=%d", uid)

	err := meta.MerchantDB.Get(&data, query)
	if err != nil {
		fmt.Println(err.Error())
		return data, errors.New("数据库错误")
	}
	RtpControlWay, _ := strconv.Atoi(data.RtpControlWay)
	data.RtpControlWay = strconv.Itoa(RtpControlWay % 10)
	return data, nil
}

func GetBolger(uid string) (BolgerData, error) {
	data := BolgerData{}
	query := fmt.Sprintf("select uid,bloger_name,bloger_date from tbl_bloger_list where uid=%s", uid)

	err := meta.MerchantDB.Get(&data, query)
	if err != nil && err != sql.ErrNoRows {

		return data, errors.New("数据库错误")
	}
	return data, nil
}

func UpdateMemberController(param UpdateMemberParam, ctx *fasthttp.RequestCtx) error {
	text := "玩家控制信息编辑修改"
	button := ""
	if param.Value == "1" {
		button = "开启"
	} else {
		button = "关闭"
	}
	switch param.Key {
	case "game_button":
		text = button + "玩家" + "游戏开关"
	case "withdraw_button":
		text = button + "玩家" + "提现开关"
	case "tax_button":
		text = button + "玩家" + "抽税开关"
	case "auto_withdraw_button":
		text = button + "玩家" + "自动出款开关"
	case "control_code_button":
		text = button + "玩家" + "控码开关"
	case "unbind_button":
		text = button + "玩家" + "掉绑开关"
	case "is_bloger":
		text = button + "玩家" + "博主开关"
	case "win_flow_multiple":
		text = "修改玩家" + "赢打码% = " + param.Value
	case "lose_flow_multiple":
		text = "修改玩家" + "输打码% = " + param.Value
	case "fake_pg_button":
		text = button + "玩家" + "假pg开关"
	case "commi_button":
		text = button + "玩家" + "佣金开关"
	case "rtp_control_way":
		if param.Value == "0" {
			text = "修改玩家" + "RTP控制方式 = 默认"
		}
		if param.Value == "1" {
			text = "修改玩家" + "RTP控制方式 = 关闭"
		}
		if param.Value == "2" {
			text = "修改玩家" + "RTP控制方式 = 手动"
		}

	case "rtp":
		text = "修改玩家" + "Rtp = " + param.Value
	case "fake_PP_rtp":
		text = "修改玩家" + "PP Rtp = " + param.Value
	case "fake_JDB_rtp":
		text = "修改玩家" + "JDB Rtp = " + param.Value
	case "fake_JILI_rtp":
		text = "修改玩家" + "JILI Rtp = " + param.Value
	case "disbind_control":
		text = "修改玩家" + "掉绑控制配置"
	case "recharge_share_type":
		if param.Value == "0" {
			text = "修改玩家" + "充值分成奖励类型 = 无充值分成奖励"
		}
		if param.Value == "1" {
			text = "修改玩家" + "充值分成奖励类型 = 首冲"
		}
		if param.Value == "2" {
			text = "修改玩家" + "充值分成奖励类型 = 复冲"
		}
		if param.Value == "3" {
			text = "修改玩家" + "充值分成奖励类型 = 首冲 复冲都有奖励"
		}
	case "recharge_share_waged_req":
		text = "修改玩家" + "充值分成奖励打码量要求 = " + param.Value
	case "recharge_share_rate":
		text = "修改玩家" + "首充充值分成奖励配置 = " + param.Value
	case "recharge_share_rate_f":
		text = "修改玩家" + "复充充值分成奖励配置 = " + param.Value
	case "commi_switch_sync_sub":
		text = button + "玩家" + "佣金开关是否同步下级"
	case "recharge_share_switch_sync_sub":
		text = button + "玩家" + "充值分成是否同步下级"
	case "sandbag_switch":
		text = "修改玩家" + "放水金额 = " + param.Value
	case "sandbag_amount_max":
		text = button + "玩家" + "放水开关"
	case "recharge_hidden_switch":
		text = button + "玩家" + "复充订单开关"
	case "syc_disbind_lv1":
		text = button + "玩家" + "同步一级掉绑配置"
	case "syc_disbind_lv2":
		text = button + "玩家" + "同步二级掉绑配置"
	case "syc_disbind_lv3":
		text = button + "玩家" + "同步三级掉绑配置"
	case "syc_charge_hidden_lv1":
		text = button + "玩家" + "同步一级隐藏订单配置"
	case "syc_charge_hidden_lv2":
		text = button + "玩家" + "同步二级隐藏订单配置"
	case "syc_charge_hidden_lv3":
		text = button + "玩家" + "同步三级隐藏订单配置"
	case "charge_hidden_button":
		text = button + "玩家" + "充值隐藏开关"
	case "charge_hidden_control_s":
		text = "修改玩家" + "首充充值订单隐藏配置 = " + param.Value
	case "charge_hidden_control_f":
		text = "修改玩家" + "复充充值订单隐藏配置 = " + param.Value
	case "charge_hidden_button_s":
		text = button + "玩家" + "首充充值隐藏开关"
	case "charge_hidden_button_f":
		text = button + "玩家" + "复充充值隐藏开关"
	}
	InsertLog(text, ctx)
	keyValue := param.Value
	if param.Key == "syc_disbind_lv1" || param.Key == "syc_disbind_lv2" || param.Key == "syc_disbind_lv3" {
		param.Value = param.Value + ",1"
	}
	if param.Key == "syc_charge_hidden_lv1" || param.Key == "syc_charge_hidden_lv2" || param.Key == "syc_charge_hidden_lv3" {
		param.Value = param.Value + ",1"
	}
	query, _, _ := dialect.Update("tbl_member_controller_button").Set(g.Record{param.Key: param.Value}).Where(g.Ex{"uid": param.Uid}).ToSQL()
	_, err := meta.MerchantDB.Exec(query)
	if err != nil {
		return errors.New("数据库错误")
	}
	//更新缓存
	userid := strconv.Itoa(int(param.Uid))
	if param.Key == "rtp_control_way" {
		param.Value = "1" + param.Value
	}

	if myredis.IsUserExis(userid) {
		ret := myredis.SetUserFieldValue(strconv.Itoa(int(param.Uid)), "tbl_member_controller_button:"+param.Key, param.Value)
		if ret == false {
			return errors.New(helper.ServerErr)
		}
	}
	if param.Key == "sandbag_switch" {
		query, _, _ = dialect.Update("tbl_member_balance").Set(g.Record{"sandbag_amount": 0}).Where(g.Ex{"uid": param.Uid}).ToSQL()
		_, err = meta.MerchantDB.Exec(query)
		if err != nil {
			return errors.New("数据库错误")
		}
		if myredis.IsUserExis(userid) {
			ret := myredis.SetUserFieldValue(strconv.Itoa(int(param.Uid)), "tbl_member_balance:sandbag_amount", "0")
			if ret == false {
				return errors.New(helper.ServerErr)
			}
		}
	}
	if param.Key == "sandbag_switch" || param.Key == "sandbag_amount_max" {
		myconn.SetSandbagRtp(strconv.Itoa(param.Uid), "0")
	}
	if param.Key == "is_bloger" {
		if param.Value == "1" {
			user, _ := MemberFindByUid(strconv.Itoa(param.Uid))
			bolgerData := BolgerData{}
			bolgerData.Uid = strconv.Itoa(param.Uid)
			bolgerData.BlogerName = user.Username
			bolgerData.BlogerDate = 0
			BolgerUpdate(bolgerData, 0)
		} else {
			bolgerData := BolgerData{}
			bolgerData.Uid = strconv.Itoa(param.Uid)
			BolgerUpdate(bolgerData, 1)
		}

	}
	if param.Key == "unbind_button" {
		//InsertLog("掉绑控制按钮开关", ctx)
		config := GameConfigByType(250)
		if config.CfgValue == "0" {
			data := UnbindControllerData{}
			data.Uid = strconv.Itoa(param.Uid)
			if param.Value == "1" {
				UpdateUnbindController(data, 0)
			} else {
				UpdateUnbindController(data, 1)
			}
		}
	}
	if param.Key == "recharge_hidden_switch" {
		//获取3级
		//uids := GetAgentTeamByLenth2(strconv.Itoa(param.Uid), 3)
		hidden := param.Value
		if param.Value == "1" {
			hidden = "1"
		} else {
			hidden = "0"
		}
		query = "update tbl_deposit set hidden=" + hidden + " where uid in(" + strconv.Itoa(param.Uid) + ") and is_first=0"
		_, err = meta.MerchantDB.Exec(query)
		//query = "update tbl_rec_recharge_share set state=" + hidden + " where uid in(" + strconv.Itoa(param.Uid) + ") and first_charge=0"
		//_, err = meta.MerchantDB.Exec(query)
	}
	controllerConfig, _ := GetMemberController(param.Uid, ctx)
	if param.Key == "syc_disbind_lv1" || param.Key == "syc_disbind_lv2" || param.Key == "syc_disbind_lv3" {
		depth, _ := strconv.Atoi((param.Key)[len(param.Key)-1:])
		uids := GetAgentTeamByDepth(strconv.Itoa(param.Uid), depth)
		if keyValue == "1" {
			sycControllerConfig(uids, "disbind_control", controllerConfig.DisbindControl)
			if controllerConfig.DisbindControl != "" {
				sycControllerConfig(uids, "unbind_button", "1")
			}
		} else {
			sycControllerConfig(uids, "disbind_control", "")
			sycControllerConfig(uids, "unbind_button", "2")
		}
		if depth == 1 {

		}
		if depth == 2 {
			uids = GetAgentTeamByDepth(strconv.Itoa(param.Uid), 1)
			sycControllerConfig(uids, "syc_disbind_lv1", "0,0")
		}
		if depth == 3 {
			uids = GetAgentTeamByDepth(strconv.Itoa(param.Uid), 1)
			sycControllerConfig(uids, "syc_disbind_lv2", "0,0")
			uids = GetAgentTeamByDepth(strconv.Itoa(param.Uid), 2)
			sycControllerConfig(uids, "syc_disbind_lv1", "0,0")
		}
	}
	if param.Key == "syc_charge_hidden_lv1" || param.Key == "syc_charge_hidden_lv2" || param.Key == "syc_charge_hidden_lv3" {
		depth, _ := strconv.Atoi((param.Key)[len(param.Key)-1:])
		uids := GetAgentTeamByDepth(strconv.Itoa(param.Uid), depth)
		if keyValue == "1" {
			sycControllerConfig(uids, "charge_hidden_control_s", controllerConfig.ChargeHiddenControlS)
			sycControllerConfig(uids, "charge_hidden_control_f", controllerConfig.ChargeHiddenControlF)
			sycControllerConfig(uids, "charge_hidden_button_s", controllerConfig.ChargeHiddenButtonS)
			sycControllerConfig(uids, "charge_hidden_button_f", controllerConfig.ChargeHiddenButtonF)
			if controllerConfig.ChargeHiddenControlS != "" || controllerConfig.ChargeHiddenControlF != "" || controllerConfig.ChargeHiddenButtonS == "1" || controllerConfig.ChargeHiddenButtonF == "1" {
				sycControllerConfig(uids, "charge_hidden_button", "1")
			}
		} else {
			sycControllerConfig(uids, "charge_hidden_control_s", "")
			sycControllerConfig(uids, "charge_hidden_control_f", "")
			sycControllerConfig(uids, "charge_hidden_button_s", "2")
			sycControllerConfig(uids, "charge_hidden_button_f", "2")
			sycControllerConfig(uids, "charge_hidden_button", "2")
		}
		if depth == 1 {

		}
		if depth == 2 {
			uids = GetAgentTeamByDepth(strconv.Itoa(param.Uid), 1)
			sycControllerConfig(uids, "syc_charge_hidden_lv1", "0,0")
		}
		if depth == 3 {
			uids = GetAgentTeamByDepth(strconv.Itoa(param.Uid), 1)
			sycControllerConfig(uids, "syc_charge_hidden_lv2", "0,0")
			uids = GetAgentTeamByDepth(strconv.Itoa(param.Uid), 2)
			sycControllerConfig(uids, "syc_charge_hidden_lv1", "0,0")
		}
	}
	return nil
}

// 批量更新配置
func sycControllerConfig(uids string, key string, value string) error {
	if uids == "" {
		return nil
	}
	query := "update tbl_member_controller_button set " + key + "='" + value + "' where uid in(" + uids + ")"
	meta.MerchantDB.Exec(query)

	arrUids := strings.Split(uids, ",")
	pipe := meta.MerchantRedis.Pipeline()
	defer pipe.Close()

	for _, uid := range arrUids {

		if myredis.IsUserExis(uid) {
			hashKey := fmt.Sprintf("UserId:%s", uid)
			field := "tbl_member_controller_button:" + key
			pipe.HSet(ctx, hashKey, field, value)
		}
	}
	// 执行 Pipeline
	_, err := pipe.Exec(ctx)
	if err != nil {
		return err
	}
	return nil
}
func UpdateTeamMemberController(param UpdateTeamMemberParam, ctx *fasthttp.RequestCtx) error {
	text := "玩家团队控制信息编辑修改"

	if param.CommiButton != "" {
		if param.CommiButton == "1" {
			text = "开启玩家" + strconv.Itoa(param.Uid) + "一级团队佣金开关"
		} else {
			text = "关闭玩家" + strconv.Itoa(param.Uid) + "一级团队佣金开关"
		}
	} else if param.RechargeHiddenSwitch != "" {
		if param.RechargeHiddenSwitch == "1" {
			text = "开启玩家" + strconv.Itoa(param.Uid) + "三级团队复充隐藏开关"
		} else {
			text = "关闭玩家" + strconv.Itoa(param.Uid) + "三级团队复充隐藏开关"
		}
	} else if param.UnbindButton != "" {
		text = "同步玩家" + strconv.Itoa(param.Uid) + strconv.Itoa(param.Level) + "级团队掉绑配置"
	} else {
		text = "同步玩家" + strconv.Itoa(param.Uid) + "三级假PG配置"
	}
	InsertLog(text, ctx)
	//获取全部下级
	uids := ""
	if param.CommiButton != "" {
		uids = GetAgentTeamByLenth(strconv.Itoa(param.Uid), 1)
		query := "update tbl_member_controller_button set commi_button=" + param.CommiButton + " where uid in(" + uids + ")"
		meta.MerchantDB.Exec(query)
	} else if param.RechargeHiddenSwitch != "" {
		uids = GetAgentTeamByLenth(strconv.Itoa(param.Uid), 3)
		query := "update tbl_member_controller_button set recharge_hidden_switch=" + param.RechargeHiddenSwitch + " where uid in(" + uids + ")"
		meta.MerchantDB.Exec(query)
	} else if param.UnbindButton != "" {
		uids = GetAgentTeamByLenth(strconv.Itoa(param.Uid), param.Level)
		query := "update tbl_member_controller_button set disbind_control='" + param.DisbindControl + "',unbind_button=" + param.UnbindButton + " where uid in(" + uids + ")"
		//fmt.Println(query)
		meta.MerchantDB.Exec(query)
	} else {
		uids = GetAgentTeamByLenth(strconv.Itoa(param.Uid), 3)
		param.RtpControlWay = "2" + param.RtpControlWay
		//query := "update tbl_member_controller_button set rtp_control_way=" + param.RtpControlWay + ",rtp=" + param.Rtp + ",fake_PP_rtp=" + param.FakePpRtp + ",fake_JDB_rtp=" + param.FakeJDBRtp + ",fake_JILI_rtp=" + param.FakeJILIRtp + " where uid in(" + uids + ")"
		query := "update tbl_member_controller_button set rtp_control_way=" + param.RtpControlWay + ",rtp=" + param.Rtp + " where uid in(" + uids + ")"
		//fmt.Println(query)
		_, err := meta.MerchantDB.Exec(query)
		if err != nil {
			fmt.Println(err.Error())
		}
	}

	arrUids := strings.Split(uids, ",")
	pipe := meta.MerchantRedis.Pipeline()
	defer pipe.Close()

	for _, uid := range arrUids {

		if myredis.IsUserExis(uid) {
			hashKey := fmt.Sprintf("UserId:%s", uid)
			if param.CommiButton != "" {
				field := "tbl_member_controller_button:commi_button"
				pipe.HSet(ctx, hashKey, field, param.CommiButton)
			} else if param.RechargeHiddenSwitch != "" {
				field := "tbl_member_controller_button:recharge_hidden_switch"
				pipe.HSet(ctx, hashKey, field, param.RechargeHiddenSwitch)
			} else if param.UnbindButton != "" {
				field := "tbl_member_controller_button:disbind_control"
				pipe.HSet(ctx, hashKey, field, param.DisbindControl)
				field = "tbl_member_controller_button:unbind_button"
				pipe.HSet(ctx, hashKey, field, param.UnbindButton)
			} else {
				field := "tbl_member_controller_button:rtp_control_way"
				pipe.HSet(ctx, hashKey, field, param.RtpControlWay)
				field = "tbl_member_controller_button:rtp"
				pipe.HSet(ctx, hashKey, field, param.Rtp)
				//field = "tbl_member_controller_button:fake_PP_rtp"
				//pipe.HSet(ctx, hashKey, field, param.FakePpRtp)
				//field = "tbl_member_controller_button:fake_JDB_rtp"
				//pipe.HSet(ctx, hashKey, field, param.FakeJDBRtp)
				//field = "tbl_member_controller_button:fake_JILI_rtp"
				//pipe.HSet(ctx, hashKey, field, param.FakeJILIRtp)
			}

		}
	}
	// 执行 Pipeline
	_, err := pipe.Exec(ctx)
	if err != nil {
		fmt.Printf("Failed to execute pipeline: %v\n", err)
		return err
	}

	fmt.Println("Successfully executed batch HSET")
	return nil
}

func UpdateTeamReMemberController(param UpdateTeamMemberParam, ctx *fasthttp.RequestCtx) error {
	//获取全部下级
	uids := GetAgentTeamByLenth(strconv.Itoa(param.Uid), 1)
	//fmt.Println(uids)
	self := MemberControllerButton{}

	query := fmt.Sprintf("select * from tbl_member_controller_button where uid=%d", param.Uid)

	err := meta.MerchantDB.Get(&self, query)
	if err != nil {
		fmt.Println(err)
		return errors.New("数据库错误")
	}
	query = "update tbl_member_controller_button set recharge_button='" + self.RechargeButton + "',recharge_share_type='" + self.RechargeShareType + "',recharge_share_waged_req='" + self.RechargeShareWagedReq + "',recharge_share_rate='" + self.RechargeShareRate + "',recharge_share_rate_f='" + self.RechargeShareRateF + "' where uid in(" + uids + ")"
	_, err = meta.MerchantDB.Exec(query)

	arrUids := strings.Split(uids, ",")
	pipe := meta.MerchantRedis.Pipeline()
	defer pipe.Close()
	for _, uid := range arrUids {
		if myredis.IsUserExis(uid) {
			hashKey := fmt.Sprintf("UserId:%s", uid)
			field := "tbl_member_controller_button:recharge_button"
			pipe.HSet(ctx, hashKey, field, self.RechargeButton)
			field = "tbl_member_controller_button:recharge_share_type"
			pipe.HSet(ctx, hashKey, field, self.RechargeShareType)
			field = "tbl_member_controller_button:recharge_share_waged_req"
			pipe.HSet(ctx, hashKey, field, self.RechargeShareWagedReq)
			field = "tbl_member_controller_button:recharge_share_rate"
			pipe.HSet(ctx, hashKey, field, self.RechargeShareRate)
			field = "tbl_member_controller_button:recharge_share_rate_f"
			pipe.HSet(ctx, hashKey, field, self.RechargeShareRateF)
		}
	}
	// 执行 Pipeline
	_, err = pipe.Exec(ctx)
	if err != nil {
		fmt.Printf("Failed to execute pipeline: %v\n", err)
		return err
	}

	fmt.Println("Successfully executed batch HSET")
	return nil
}

func UpdateTeamRemarkMemberController(param UpdateMemberParam, ctx *fasthttp.RequestCtx) error {
	//获取全部下级
	param.Value = "team:" + param.Value
	uids := GetAgentTeamByLenth(strconv.Itoa(param.Uid), 3)
	query := "update tbl_member_base set remake='" + param.Value + "' where uid in(" + uids + ")"
	fmt.Println(query)
	_, err := meta.MerchantDB.Exec(query)

	arrUids := strings.Split(uids, ",")
	pipe := meta.MerchantRedis.Pipeline()
	defer pipe.Close()
	for _, uid := range arrUids {
		if myredis.IsUserExis(uid) {
			hashKey := fmt.Sprintf("UserId:%s", uid)
			field := "tbl_member_base:remake"
			pipe.HSet(ctx, hashKey, field, param.Value)
		}
	}
	// 执行 Pipeline
	_, err = pipe.Exec(ctx)
	if err != nil {
		fmt.Printf("Failed to execute pipeline: %v\n", err)
		return err
	}

	fmt.Println("Successfully executed batch HSET")
	return nil
}

func GetMemberRemarkLog(param MemberLoginLogParam, ctx *fasthttp.RequestCtx) (BackgroundLogRetData, error) {
	data := BackgroundLogRetData{}

	where := "(url='/api/member/info/update' or  url='/api/member/remark/team/update') and param like '%\"key\":\"remake%'"
	oderBy := "id"
	oderType := "desc"
	if param.Uid != 0 {
		where += " and param like'%\"uid\":" + strconv.Itoa(param.Uid) + ",%'"
	}

	//loginUser := GetLoginUser(ctx)
	//if loginUser.Operator != "" {
	//	where += " and b.operator_id=" + loginUser.Operator
	//}
	//if loginUser.Businsess != "" {
	//	where += " and b.business_id=" + loginUser.Businsess
	//}
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}
	//join := " left join tbl_member_base as b on b.uid=a.uid"          //玩家表

	order := oderBy + " " + oderType

	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from tbl_background_log where " + where

		fmt.Println(count)
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {

			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	field := "*"
	query := "select " + field + " from tbl_background_log where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	fmt.Println(query)
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {

		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	adminList, _ := GetAdminMap()
	businessList, _ := GetBusinessMap()
	operatorList, _ := GetOperatorMap()
	for key, value := range data.D {
		len := len(strconv.Itoa(value.OptId))

		if len == 6 {
			(data.D)[key].Name = "渠道:" + operatorList[strconv.Itoa(value.OptId)]
		} else if len == 7 {
			(data.D)[key].Name = "业务员:" + businessList[strconv.Itoa(value.OptId)]
		} else {
			(data.D)[key].Name = "总后台:" + adminList[strconv.Itoa(value.OptId)]
		}

		param := UpdateMemberParam{}
		json.Unmarshal([]byte(value.Param), &param)
		(data.D)[key].Param = param.Value
	}
	return data, nil
}

func GetMemberChangeParentLog(param MemberLoginLogParam, ctx *fasthttp.RequestCtx) (BackgroundLogRetData, error) {
	data := BackgroundLogRetData{}

	where := "a.url='/api/agent/change/parent'"
	oderBy := "a.id"
	oderType := "desc"
	if param.Uid != 0 {
		where += " and a.param like'%\"uid\":" + strconv.Itoa(param.Uid) + ",%'"
	}

	if param.StartTime != "" {
		where += " and a.date>='" + param.StartTime + "'"
	}
	if param.EndTime != "" {
		where += " and a.date<'" + param.StartTime + "'"
	}

	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		where += " and b.operator_id=" + loginUser.Operator
	}
	if loginUser.Businsess != "" {
		where += " and b.business_id=" + loginUser.Businsess
	}
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}
	join := " left join tbl_member_base as b on b.uid=SUBSTRING(a.param, 8, 8)" //玩家表

	order := oderBy + " " + oderType

	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from tbl_background_log as a " + join + " where " + where

		fmt.Println(count)
		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {

			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	field := "a.*"
	query := "select " + field + " from tbl_background_log as a " + join + "where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	fmt.Println(query)
	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {

		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	adminList, _ := GetAdminMap()
	businessList, _ := GetBusinessMap()
	operatorList, _ := GetOperatorMap()
	for key, value := range data.D {
		len := len(strconv.Itoa(value.OptId))

		if len == 6 {
			(data.D)[key].Name = "渠道:" + operatorList[strconv.Itoa(value.OptId)]
		} else if len == 7 {
			(data.D)[key].Name = "业务员:" + businessList[strconv.Itoa(value.OptId)]
		} else {
			(data.D)[key].Name = "总后台:" + adminList[strconv.Itoa(value.OptId)]
		}
		param := ChangeParentParam{}
		json.Unmarshal([]byte(value.Param), &param)

		param.BeforeOperatorId = operatorList[param.BeforeOperatorId]
		param.BeforeBusinessId = businessList[param.BeforeBusinessId]

		param.OperatorId = operatorList[param.OperatorId]
		param.BusinessId = businessList[param.BusinessId]

		newParam, _ := json.Marshal(param)
		(data.D)[key].Param = string(newParam)
	}
	return data, nil
}

func MemberLoginLog(param MemberLoginLogParam, ctx *fasthttp.RequestCtx) (MemberLoginLogRetData, error) {
	data := MemberLoginLogRetData{}
	where := "1=1"
	oderBy := "login_time"
	oderType := "desc"
	if param.Uid != 0 {
		where += " and a.uid=" + strconv.Itoa(param.Uid)
	}
	if param.LoginIp != "" {
		where += " and a.login_ip=" + param.LoginIp
	}
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		where += " and c.id=" + loginUser.Operator
	}
	if loginUser.Businsess != "" {
		where += " and d.id=" + loginUser.Businsess
	}
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}
	join := " left join tbl_member_base as b on b.uid=a.uid"          //玩家表
	join += " left join tbl_operator_info as c on c.id=b.operator_id" //渠道表
	join += " left join tbl_business_info as d on d.id=b.business_id" //业务员表

	order := oderBy + " " + oderType

	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from tbl_member_login_log as a " + join + " where " + where

		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {

			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	field := "a.*," +
		"ifnull(b.username,'') username," +
		"ifnull(c.id,'') operator_id," +
		"ifnull(c.operator_name,'') operator_name," +
		"ifnull(d.id,'') business_id," +
		"ifnull(d.account_name,'') as business_name"
	query := "select " + field + " from tbl_member_login_log  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)

	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {

		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return data, nil
}

type SameIpRetData struct {
	T int64        `json:"total"`
	D []SameIpData `json:"d"`
}
type SameIpData struct {
	Uid         string `json:"uid" db:"uid" cbor:"uid"`
	CreatedAt   uint32 `json:"created_at" db:"created_at" cbor:"created_at"`          //注册时间
	CreatedIp   string `json:"created_ip" db:"created_ip" cbor:"created_ip"`          //注册ip
	Phone       string `json:"phone" db:"phone" cbor:"phone"`                         //手机
	LastLoginAt uint32 `json:"last_login_at" db:"last_login_at" cbor:"last_login_at"` //登陆时间
	LastLoginIp string `json:"last_login_ip" db:"last_login_ip" cbor:"last_login_ip"` //登陆ip
}

func SameIpList(param MemberListParam, ctx *fasthttp.RequestCtx) (SameIpRetData, error) {
	data := SameIpRetData{}
	list := MemberPageData{}
	userInfo, err := MemberFindByUid(param.Uid)
	if err != nil {
		return data, err
	}
	auth, err := UserAuthCheck(userInfo, ctx)
	if auth == false {
		return data, err
	}
	param.RegIp = userInfo.CreatedIp
	param.Uid = ""
	list, err = MemberList(param, ctx)
	if err != nil {
		return data, err
	}
	for _, value := range list.D {
		singleData := SameIpData{
			Uid:         value.Uid,
			CreatedAt:   value.CreatedAt,
			CreatedIp:   value.CreatedIp,
			Phone:       value.Phone,
			LastLoginAt: value.LastLoginAt,
			LastLoginIp: value.LastLoginIp,
		}
		data.D = append(data.D, singleData)
	}
	data.T = list.T
	return data, nil
}

func GetWagRequire(param WagRequireParam, ctx *fasthttp.RequestCtx) (WagRequireRetData, error) {
	data := WagRequireRetData{}
	where := "1=1"
	oderBy := "AddTime"
	oderType := "desc"
	if param.Uid != 0 {
		where += " and a.uid=" + strconv.Itoa(param.Uid)
	}
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		where += " and b.operator_id=" + loginUser.Operator
	}
	if loginUser.Businsess != "" {
		where += " and b.business_id=" + loginUser.Businsess
	}
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}
	join := " left join tbl_member_base as b on b.uid=a.uid"       //玩家表
	join += " left join tbl_flow_config as c on c.ty=a.ChangeType" //类型表
	//join += " left join tbl_operator_info as c on c.id=b.operator_id" //渠道表
	//join += " left join tbl_business_info as d on d.id=b.business_id" //业务员表

	order := oderBy + " " + oderType

	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from tbl_member_wage_require as a " + join + " where " + where

		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {

			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	field := "a.*,ifnull(c.name,'无') ChangeName,(CASE WHEN a.NeedWageRequire=0 THEN 0 ELSE  100*CurWageRequire/NeedWageRequire END) as com_rate"
	query := "select " + field + " from tbl_member_wage_require  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)

	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {

		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}

	return data, nil
}

func GetWagRequireSummary(param WagRequireParam, ctx *fasthttp.RequestCtx) (WagRequire, error) {
	data := WagRequire{}

	//统计
	sfield := "ifnull(sum(CurWageRequire),0) CurWageRequire," +
		"ifnull(sum(NeedWageRequire),0) NeedWageRequire"
	query := "select " + sfield + " from tbl_member_wage_require where  uid=" + strconv.Itoa(param.Uid)

	err := meta.MerchantDB.Get(&data, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	data.NeedWageRequire = data.NeedWageRequire - data.CurWageRequire
	return data, nil
}

func WagRequireOpt(param WagRequireOptParam, ctx *fasthttp.RequestCtx) error {
	userInfo, err := MemberFindByUid(strconv.Itoa(int(param.Uid)))

	if err != nil {
		return err
	}
	auth, err := UserAuthCheck(userInfo, ctx)
	if auth == false {
		return err
	}

	if param.Otype == 1 {
		//myUserHelp.AdminAddUserWageRequire(strconv.Itoa(param.Uid), 0, math.Abs(param.Wage))
		// 加码操作 操作加码后，给玩家插入一条打码任务。同时，临时额度和基础额度都减去打码量对应的金额
		uid := strconv.Itoa(param.Uid)
		ChangeMoney := math.Abs(param.Wage)
		myUserHelp.AddUserWageItem(uid, ChangeMoney, helper.AdminAddWagedOnly)

		myUserHelp.AddUnlockAmount(uid, -ChangeMoney)
		if myUserHelp.GetUnlockAmount(uid) < 0 {
			myUserHelp.SetUnlockAmount(uid, 0)
		}

		myUserHelp.AddAgencyAmount(uid, -ChangeMoney)
		if myUserHelp.GetAgencyAmount(uid) < 0 {
			myUserHelp.SetAgencyAmount(uid, 0)
		}
	}
	if param.Otype == 2 {
		myUserHelp.AdminAddUserWageRequire(strconv.Itoa(param.Uid), math.Abs(param.Wage), 0)
	}
	if param.Otype == 3 {
		sqlSelect := fmt.Sprintf("update  tbl_member_wage_require set CurWageRequire=NeedWageRequire, status=1,WageFinishTime='%s' "+
			"where uid=%d and status = 0", time.Now().Format("2006-01-02 15:04:05"), param.Uid)
		fmt.Println(sqlSelect)
		meta.MerchantDB.Exec(sqlSelect)
		if myredis.IsUserExis(strconv.Itoa(param.Uid)) {
			myUserHelp.ClearUserWagedRequire(strconv.Itoa(param.Uid))
		}

		myUserHelp.LoadUserWage(strconv.Itoa(param.Uid))
	}
	myUserHelp.SaveUserWageRequire(strconv.Itoa(param.Uid))
	return nil
}
